<template>
  <div class="x-diy-column">
    <x-button :size="buttonSize" :loading="loading" @click="handleVisible">{{ title }}</x-button>
    <x-drawer v-model:visible="visible" :title="title" width="500px">
      <n-checkbox-group v-if="visible" v-model:value="checkedList" size="small">
        <div class="x-diy-column-list">
          <div v-for="(item, index) in list" :key="index" class="item">
            <n-checkbox :value="item.value" :disabled="index < min" :label="item.label" />
          </div>
        </div>
      </n-checkbox-group>
      <template #footer>
        <x-button @click="handleCancelDrawer">取消</x-button>
        <x-button type="primary" @click="handleSubmit">保存</x-button>
      </template>
    </x-drawer>
  </div>
</template>

<script lang="ts">
  import { computed, defineComponent, reactive, toRefs, watch } from 'vue'
  import { NCheckboxGroup, NCheckbox } from 'naive-ui'
  import { XButton, XDrawer } from '@/components'
  import { useStore } from '@/store'
  import { useDictionary } from '@/hooks'

  export default defineComponent({
    name: 'XDiyColumn',
    components: {
      NCheckboxGroup,
      NCheckbox,
      XDrawer,
      XButton
    },
    props: {
      value: {
        type: [Array, Object],
        default: () => []
      },
      // 必填，缓存时需要使用
      name: {
        type: String,
        default: 'name',
        required: true
      },
      title: {
        type: String,
        default: '自定义列'
      },
      min: {
        type: Number,
        default: 4
      },
      // 使用api
      api: {
        type: String,
        default: ''
      },
      // 使用字典
      isDictionary: {
        type: Boolean,
        default: false
      },
      // 直接使用数据
      data: {
        type: Array,
        default: () => []
      },
      // 默认选中值
      defaultValue: {
        type: Array,
        default: () => []
      },
      // 按钮大小
      buttonSize: {
        type: String,
        default: 'medium'
      }
    },
    emits: ['update:value'],
    setup($props, { emit: $emit }) {
      const $dictionary = useDictionary()
      const $store = useStore()
      const $state = reactive({
        ...toRefs($props),
        loading: false,
        visible: false,
        // 字典
        dictionary: computed(() => $store.getters.dictionary),
        localName: computed(() => `LOCAL-DIY-COLUMN-${$props.name}`),
        list: [],
        checkedList: [],
        oldVal: []
      })

      const initList = async () => {
        let localValue = localStorage.getItem($state.localName)
        if (!localValue && $props.defaultValue.length) {
          localValue = JSON.stringify($props.defaultValue)
        }
        $state.loading = true
        if ($props.isDictionary) {
          await $dictionary.get($props.name)
          $state.list = $state.dictionary[$props.name] || []
        } else if ($props.api) {
          const { data } = await $store.dispatch($props.api)
          $state.list = data || []
        } else {
          $state.list = $props.data || []
        }
        $state.loading = false
        // 最少选中数据
        if ($props.min && $state.list.length) {
          const len = localValue ? $props.min : $state.list.length
          for (let i = 0; i < len; i++) {
            $state.checkedList.push($state.list[i].value)
          }
        }
        // 处理缓存数据
        if (localValue) {
          try {
            const arr = JSON.parse(localValue)
            if (Object.prototype.toString.call(arr) === '[object Array]') {
              arr.forEach((item: string) => {
                if (!$state.checkedList.some((s) => s === item)) {
                  $state.checkedList.push(item)
                }
              })
            }
          } catch (e) {
            console.warn('处理缓存数据错误 ', e)
          }
        }
        $state.oldVal = JSON.parse(JSON.stringify($state.checkedList))
        // 初始化完成
        handleSubmit()
      }
      initList()

      // watch
      watch(
        () => $props.name,
        () => {
          initList()
        }
      )
      watch(
        () => $state.visible,
        () => {
          // 关闭抽屉时，重置数据
          $state.checkedList = $state.oldVal
        }
      )

      const handleVisible = () => {
        $state.visible = true
      }

      const handleCancelDrawer = () => {
        $state.visible = false
      }

      const handleSubmit = () => {
        // 缓存至本地
        localStorage.setItem($state.localName, JSON.stringify($state.checkedList))
        // console.log(11, $state.checkedList)
        $emit('update:value', $state.checkedList)
        $state.oldVal = $state.checkedList
        $state.visible = false
      }

      return {
        ...toRefs($state),
        handleVisible,
        handleSubmit,
        handleCancelDrawer
      }
    }
  })
</script>

<style lang="scss" scoped>
  .x-diy-column-list {
    display: flex;
    flex-wrap: wrap;
    .item {
      width: 150px;
      padding: 5px;
    }
  }
</style>
